﻿Imports WiremetModel.Entities.OEM
Imports WIREMET.DictionaryExtensions

Public Class WysylkaView

    Private _wysylkaDictionary As Dictionary(Of Integer, Wysylka)
    Private _unitOfWork As UnitOfWork
    Private _detailsPanelWidth As Integer

    Public Sub New()
        InitializeComponent()
        _unitOfWork = New UnitOfWork()
        RefreshViewData()
        SetInitialFilter()
        RunFilter(CreateFilter())

        _detailsPanelWidth = sc_WysylkaView.Panel2.Width
        ChangeDetailsPanelVisibility()
    End Sub


    Private Sub WysylkaView_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        _unitOfWork.Dispose()
    End Sub


    Private Sub RefreshViewData()

        Dim wysylkaRepository As New Repository(Of Wysylka)(_unitOfWork)
        Dim klientRepository As New Repository(Of Klient)(_unitOfWork)
        Dim statusWysylkiRepository As New Repository(Of StatusWysylki)(_unitOfWork)
        Dim pracownikRepository As New Repository(Of Pracownik)(_unitOfWork)

        _wysylkaDictionary = wysylkaRepository.GetAll().ToDictionary(Function(x) x.Id, Function(x) x)
        Dim klientList As IEnumerable(Of Klient) = klientRepository.GetAll().OrderBy(Function(x) x.NazwaSkrocona)
        Dim statusWysylkiList As IEnumerable(Of StatusWysylki) = statusWysylkiRepository.GetAll().OrderBy(Function(x) x.Nazwa)
        Dim pracownikList As IEnumerable(Of Pracownik) = pracownikRepository.GetAll().OrderBy(Function(x) x.ToString())

        InitializeFilterComboBox(cmb_filter_NazwaFirmy, klientList.ToDictionary(Function(x) x.Id, Function(x) x.NazwaSkrocona))
        InitializeFilterComboBox(cmb_filter_StatusWysylki, statusWysylkiList.ToDictionary(Function(x) x.Id, Function(x) x.Nazwa))
        InitializeFilterComboBox(cmb_filter_Pracownik, pracownikList.ToDictionary(Function(x) x.Id, Function(x) x.ToString()))

    End Sub


    Private Sub InitializeFilterComboBox(ByRef cmbFilter As ComboBox, ByVal data As Dictionary(Of Integer, String))

        cmbFilter.DataSource = New BindingSource(data, Nothing)
        cmbFilter.DisplayMember = "Value"
        cmbFilter.ValueMember = "Key"
        cmbFilter.AutoCompleteCustomSource.Clear()
        cmbFilter.AutoCompleteCustomSource.AddRange(data.Values.OrderBy(Function(x) x).ToArray())
        cmbFilter.SelectedIndex = -1

    End Sub

    Private Sub SetInitialFilter()
        dtp_DataRealizacjiPoczatkowa.Value = DateTime.Today.AddDays(-30).Date
    End Sub


    Private Sub RefreshWysylkiTable(ByVal wysylkiList As IEnumerable(Of Wysylka))

        dgv_Wysylki.Rows.Clear()

        For Each wysylka As Wysylka In wysylkiList

            Dim index As Integer = dgv_Wysylki.Rows.Add(
                wysylka.Id,
                wysylka.Numer,
                wysylka.Zlecenie.Klient.NazwaSkrocona,
                wysylka.Data.ToShortDateString(),
                wysylka.Zlecenie.StatusWysylki.Nazwa)
        Next
    End Sub

#Region "Filter"

    Private Structure Filter
        Public numerWysylki As String
        Public numerZlecenia As String
        Public klientId As Integer
        Public isDateFilterEnabled As Boolean
        Public dateStart As Date
        Public dateEnd As Date
        Public statusWysylkiId As Integer
        Public gatunekId As Integer
        Public wymiar As String
        Public pracownikId As Integer
    End Structure


    Private Function CreateFilter() As Filter
        Return New Filter With
        {
            .numerWysylki = txt_filter_NumerWysylki.Text.Trim(),
            .numerZlecenia = txt_filter_NumerZlecenia.Text.Trim(),
            .klientId = CInt(cmb_filter_NazwaFirmy.SelectedValue),
            .isDateFilterEnabled = cb_DataRealizacji.Checked,
            .dateStart = dtp_DataRealizacjiPoczatkowa.Value.Date,
            .dateEnd = dtp_DataRealizacjiKoncowa.Value.Date,
            .statusWysylkiId = CInt(cmb_filter_StatusWysylki.SelectedValue),
            .wymiar = txt_filter_Wymiar.Text.Trim(),
            .pracownikId = CInt(cmb_filter_Pracownik.SelectedValue)
        }
    End Function

    Private Function IsWysylkaSatisfiedByFilter(ByVal wysylka As Wysylka, ByVal filter As Filter) As Boolean

        Return wysylka.Numer.StartsWith(filter.numerWysylki, StringComparison.CurrentCultureIgnoreCase) AndAlso
               wysylka.Zlecenie.Numer.StartsWith(filter.numerZlecenia, StringComparison.CurrentCultureIgnoreCase) AndAlso
               (filter.klientId = 0 OrElse wysylka.Zlecenie.Klient.Id = filter.klientId) AndAlso
               (Not filter.isDateFilterEnabled OrElse (wysylka.Data >= filter.dateStart AndAlso wysylka.Data <= filter.dateEnd)) AndAlso
               (filter.statusWysylkiId = 0 OrElse wysylka.Zlecenie.StatusWysylki.Id = filter.statusWysylkiId) AndAlso
               (String.IsNullOrEmpty(filter.wymiar) OrElse wysylka.Zlecenie.PozycjeZlecenia.Where(Function(x) x.Wymiar.StartsWith(filter.wymiar, StringComparison.CurrentCultureIgnoreCase)).Any()) AndAlso
               (filter.pracownikId = 0 OrElse wysylka.Pracownik.Id = filter.pracownikId)
    End Function


    Private Sub RunFilter(ByVal filter As Filter)

        Dim filteredWysylki As New List(Of Wysylka)

        For Each wysylka As Wysylka In _wysylkaDictionary.Values
            If CBool(IsWysylkaSatisfiedByFilter(wysylka, filter)) Then
                filteredWysylki.Add(wysylka)
            End If
        Next

        dgv_Wysylki.Rows.Clear()
        RefreshWysylkiTable(filteredWysylki.OrderByDescending(Function(x) x.Data))

        ComboBoxCleanupWhenNoValueSelected(cmb_filter_NazwaFirmy)
        ComboBoxCleanupWhenNoValueSelected(cmb_filter_Pracownik)
        ComboBoxCleanupWhenNoValueSelected(cmb_filter_StatusWysylki)

    End Sub

    Private Sub ComboBoxCleanupWhenNoValueSelected(ByRef comboBox As ComboBox)
        If comboBox.SelectedValue Is Nothing Then
            comboBox.ResetText()
        End If
    End Sub


    Private Sub ClearFilter()

        txt_filter_NumerWysylki.Text = String.Empty
        txt_filter_NumerZlecenia.Text = String.Empty
        cmb_filter_NazwaFirmy.ResetText()
        cmb_filter_NazwaFirmy.SelectedIndex = -1
        cb_DataRealizacji.Checked = False
        cmb_filter_StatusWysylki.ResetText()
        cmb_filter_StatusWysylki.SelectedIndex = -1
        txt_filter_Wymiar.Text = String.Empty
        cmb_filter_Pracownik.ResetText()
        cmb_filter_Pracownik.SelectedIndex = -1

    End Sub


    Private Sub btn_RunFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_RunFilter.Click
        RunFilter(CreateFilter())
    End Sub


    Private Sub RefreshView()
        Dim filter As Filter = CreateFilter()
        _unitOfWork.Dispose()
        _unitOfWork = New UnitOfWork()
        RefreshViewData()
        'ClearFilter()
        'SetInitialFilter()
        RunFilter(filter)
    End Sub

    Private Sub btn_Refresh_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        RefreshView()
    End Sub

    Private Sub ts_btn_RefreshView_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_RefreshView.Click
        RefreshView()
    End Sub

    Private Sub btn_ClearFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_ClearFilter.Click
        ClearFilter()
        RunFilter(CreateFilter())
    End Sub


    Private Sub filterInput_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles txt_filter_NumerWysylki.KeyDown, cmb_filter_NazwaFirmy.KeyDown, cmb_filter_StatusWysylki.KeyDown, txt_filter_Wymiar.KeyDown, txt_filter_NumerZlecenia.KeyDown, cmb_filter_Pracownik.KeyDown
        If e.KeyCode = Keys.Enter Then
            RunFilter(CreateFilter())
        End If
    End Sub


    Private Sub dtpDataRealizacji_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dtp_DataRealizacjiPoczatkowa.ValueChanged, dtp_DataRealizacjiKoncowa.ValueChanged
        cb_DataRealizacji.Checked = True
    End Sub

#End Region


    Private Sub RefreshDetailsPozycjeZleceniaTable(ByVal pozycjeZleceniaList As IEnumerable(Of PozycjaZlecenia))
        dgv_PozycjeZlecenia.Rows.Clear()
        For Each pozycjaZlecenia As PozycjaZlecenia In pozycjeZleceniaList
            dgv_PozycjeZlecenia.Rows.Add(
                pozycjaZlecenia.Id,
                pozycjaZlecenia.NumerPozycji,
                pozycjaZlecenia.Wymiar,
                pozycjaZlecenia.Gatunek.NazwaAng,
                pozycjaZlecenia.Ilosc.ToString(),
                pozycjaZlecenia.Cena.ToString() + " " + pozycjaZlecenia.Waluta.Nazwa)
        Next
    End Sub


    Private Sub RefreshDetails(ByVal wysylka As Wysylka)

        txt_DataUtworzenia.Text = CStr(wysylka.Zlecenie.DataUtworzenia)
        txt_Pracownik.Text = wysylka.Pracownik.Nazwisko & " " & wysylka.Pracownik.Imie
        txt_SposobZamowienia.Text = wysylka.Zlecenie.SposobZamowienia.Nazwa
        txt_StatusZlecenia.Text = wysylka.Zlecenie.Status.Nazwa
        txt_Uwagi.Text = wysylka.Zlecenie.Uwagi
        gb_Details.Text = "SZCZEGÓŁY ZLECENIA - " + wysylka.Zlecenie.Numer
        RefreshDetailsPozycjeZleceniaTable(wysylka.PaczkiWysylki.SelectMany(Function(x) x.Druty.Select(Function(y) y.Drut.PozycjaSchematu.Schemat.PozycjaZlecenia.PozycjaZleceniaOEM)).Distinct.OrderBy(Function(x) x.NumerPozycji))
        ' wysylka.Zlecenie.PozycjeZlecenia.OrderBy(Function(x) x.NumerPozycji))
    End Sub





    Private Sub RefreshDetails()
        If Not sc_WysylkaView.Panel2Collapsed AndAlso Not dgv_Wysylki.SelectedRows.Count = 0 Then
            Dim wysylkaId As Integer = CInt(dgv_Wysylki.SelectedRows(0).Cells("WysylkaId").Value)
            RefreshDetails(_wysylkaDictionary(wysylkaId))
        Else
            gb_Details.Text = "SZCZEGÓŁY ZLECENIA"
        End If
    End Sub


    Private Sub dgv_Wysylki_SelectionChanged(ByVal sender As System.Object, ByVal e As EventArgs) Handles dgv_Wysylki.SelectionChanged
        RefreshDetails()
    End Sub


    Private Function GetSelectedWysylka() As Wysylka
        Return _wysylkaDictionary(CInt(dgv_Wysylki.SelectedRows(0).Cells("WysylkaId").Value))
    End Function


    Private Sub EnsureWysylkaIsSelected()
        If dgv_Wysylki.SelectedRows.Count = 0 Then
            Throw New Exception("Proszę, wybierz wysyłkę, aby kontynuować.")
        End If
    End Sub


    Private Sub dgv_Wysylki_CellMouseDoubleClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs) Handles dgv_Wysylki.CellMouseDoubleClick
        Try
            EnsureWysylkaIsSelected()
            Dim selectedWysylka As Wysylka = GetSelectedWysylka()
            Dim wysylkaForm As New frmWysylka2(selectedWysylka.Zlecenie.ZlecenieTracking.First().Id, selectedWysylka.Id)
            'WTF? Dim wysylkaForm As New frmWysylka2(selectedWysylka.Zlecenie.ZlecenieTracking.First().Id, 0)  
            wysylkaForm.MdiParent = MdiParent
            wysylkaForm.Show()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End Try
    End Sub


    Private Sub ChangeDetailsPanelVisibility()
        If sc_WysylkaView.Panel2Collapsed Then
            sc_WysylkaView.Panel2Collapsed = False
            Me.Width += _detailsPanelWidth + sc_WysylkaView.SplitterWidth
        Else
            _detailsPanelWidth = sc_WysylkaView.Panel2.Width
            Me.Width -= _detailsPanelWidth + sc_WysylkaView.SplitterWidth
            sc_WysylkaView.Panel2Collapsed = True
        End If
        Refresh()
    End Sub

    Private Sub ts_btn_Details_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_Details.Click
        ChangeDetailsPanelVisibility()
        RefreshDetails()
    End Sub

    Private Sub ts_btn_GenerateInvoice_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_GenerateInvoice.Click
        Try
            EnsureWysylkaIsSelected()
            Cursor = Cursors.WaitCursor
            Dim selectedWysylka As Wysylka = GetSelectedWysylka()
            Dim fakturaReportService As New FakturaReportService()
            Dim fakturaReport As FakturaReport = fakturaReportService.GenerateReport(selectedWysylka)

            If fakturaReport IsNot Nothing Then
                Dim printViewer As frmPrintViewer = New frmPrintViewer(fakturaReport, False)
                printViewer.WindowState = FormWindowState.Maximized
                printViewer.ShowDialog()
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub ts_btn_Certificates_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_Certificates.Click
        Try
            EnsureWysylkaIsSelected()
            Dim selectedWysylka As Wysylka = GetSelectedWysylka()

            Dim orderLineSelectionDialog As New WireCertificateOrderLineSelectionDialog(selectedWysylka, _unitOfWork)
            'orderLineSelectionDialog.MdiParent = MdiParent
            'orderLineSelectionDialog.Show()
            orderLineSelectionDialog.ShowDialog()

            Cursor = Cursors.WaitCursor
            RefreshView()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    
End Class